/*
 * Created on 22/09/2009
 *
 */
package com.stefanini.pe.bbva.mbl.smanager;

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Vector;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.stefanini.pe.bbva.mbl.carga.in.to.UsuarioSesion;
import com.stefanini.pe.bbva.mbl.in.utils.Constantes;
import com.stefanini.pe.framework.common.Convert;
import com.stefanini.pe.framework.common.StringUtil;
import com.stefanini.pe.framework.io.BinaryFormatter;
//import com.stefanini.pe.framework.common.StringUtil;
//import com.stefanini.pe.framework.io.BinaryFormatter;
/**
 * @author jlezama
 *
 */
public class SessionManager
{
    // Fields
	private static ItemSessionCollection oItemSessionCollection;
	private static String SessionIdCookieName = Constantes.NOMBRE_COOKIE;
	private static String m_strFolderName;
    //private static UsuarioSesion _usuario = new UsuarioSesion();
    

    // Methods
    public static void Clear(HttpSession session,HttpServletRequest request,HttpServletResponse response) throws Exception
    {
        if (IsOpen())
        {
            Close(session,request,response);
        }
        String path = StringUtil.Empty;
        String sessionID = GetSessionID(session,request,response);
        if (sessionID.trim().length() == 0)
        {
            path = GetFileName(session,request,response,GenerateSessionID(session,request,response));
        }
        else
        {
            path = GetFileName(session,request,response,sessionID);
        }
        try
        {
            File f = new File(path);
            if (f.exists())
            {f.delete();}
        }
        catch(Exception ex)
        { }
    }

    public static void Close(HttpSession session,HttpServletRequest request,HttpServletResponse response) throws Exception
    {
        if (oItemSessionCollection != null)
        {
            oItemSessionCollection.Sort();
            String fileName = GetFileName(session,request,response,GetSessionID(session,request,response));
            File f = new File(fileName);
            if (!f.exists())
            {
                f.createNewFile();
            }            
            BinaryFormatter.serialize(oItemSessionCollection,fileName);            
            oItemSessionCollection = null;
        }
    }

    public static boolean Contains(HttpSession session,HttpServletRequest request,HttpServletResponse response,String strKey) throws SessionNotOpenException
    {
    	boolean booRetorno = false;
        if (!IsOpen())
        {
        	SessionNotOpenException ex = new SessionNotOpenException();
            throw ex;
        }
        if (oItemSessionCollection.IndexOf(strKey)!=-1)
        { booRetorno = true;}
        else
        { booRetorno = false;}
        return booRetorno;
    }

    private static String GenerateSessionID(HttpSession session,HttpServletRequest request,HttpServletResponse response)
    {       	
    	if (session != null)
        {
            return session.getId();
        }
    	
        String str = Convert.toString(Calendar.getInstance().get(Calendar.YEAR)) + Convert.toString(Calendar.getInstance().get(Calendar.MONTH)) + Convert.toString(Calendar.getInstance().get(Calendar.DAY_OF_WEEK_IN_MONTH)) + Convert.toString(Calendar.getInstance().get(Calendar.HOUR_OF_DAY)) + Convert.toString(Calendar.getInstance().get(Calendar.MINUTE)) + Convert.toString(Calendar.getInstance().get(Calendar.SECOND)) + Convert.toString(Calendar.getInstance().get(Calendar.MILLISECOND)) + Convert.toString(session.getServletContext().hashCode());
                
        /*if (HttpContext.Current.Request.Browser.Cookies)
        {*/
        Cookie cookie = new Cookie(Constantes.NOMBRE_COOKIE, str);
        cookie.setMaxAge(-1);
        response.addCookie(cookie);           
            
            //HttpContext.Current.Request.Cookies.Add(cookie);
            //HttpContext.Current.Response.Cookies.Add(cookie);
            //return str;
        //}
        //request.QueryString.Add("tsSessionId", str);
        return str;
    }

    public static Object Get(HttpSession session,HttpServletRequest request,HttpServletResponse response,String strKey) throws Exception
    {
        if (!IsOpen())
        {
            throw new SessionNotOpenException();
        }
        if (oItemSessionCollection.Contains(strKey))
        {
            return oItemSessionCollection.Item(strKey).getContent();
        }
        return null;
    }

    private static String GetFileName(HttpSession session,HttpServletRequest request,HttpServletResponse response,String SessionID)
    {
        String str = SessionID + ".ses";
        if ((m_strFolderName == null) || (m_strFolderName.trim().length() == 0))
        {
            m_strFolderName = Constantes.RUTA_ARCHIVOS + "\\sesiones";
        }
        return (m_strFolderName + "/" + str);
    }

    private static String GetSessionID(HttpSession session,HttpServletRequest request,HttpServletResponse response)
    {
        if (session != null)
        {
            return session.getId();
        }
        /*if (!HttpContext.Current.Request.Browser.Cookies)
        {
            return Convert.ToString(HttpContext.Current.Request.QueryString["tsSessionId"]);
        }*/
        if (request.getCookies()!=null)
        {
            	int posicion=Arrays.binarySearch(request.getCookies(),Constantes.NOMBRE_COOKIE);
            	if(posicion!=-1)
            	{return request.getCookies()[posicion].getValue();}
        }
        return GenerateSessionID(session,request,response);
    }

    public static boolean IsOpen()
    {
        return (oItemSessionCollection != null);
    }

    public static void Open(HttpSession session,HttpServletRequest request,HttpServletResponse response) throws Exception
    {
        if (oItemSessionCollection == null)
        {
            Refresh(session,request,response);
        }
    }

    public static void Open(HttpSession session,HttpServletRequest request,HttpServletResponse response,String sessionFolder)throws Exception
    {
        setSessionFolder(session,request,response,sessionFolder);
        Open(session,request,response);
    }

    public static void Refresh(HttpSession session,HttpServletRequest request,HttpServletResponse response) throws Exception
    {
        FileInputStream stream;
        String path = StringUtil.Empty;
        String sessionID = GetSessionID(session,request,response);
        if (sessionID.trim().length() == 0)
        {
            path = GetFileName(session,request,response,GenerateSessionID(session,request,response));
        }
        else
        {
            path = GetFileName(session,request,response,sessionID);
        }
        //BinaryFormatter formatter = new BinaryFormatter();
        File f = new File(path);
        if (f.exists())
        {        	
            //stream = new FileInputStream(f);            
        	ObjectInputStream objstream = new ObjectInputStream(new FileInputStream(path));
        	oItemSessionCollection = (ItemSessionCollection)objstream.readObject();
    		objstream.close();
            //oItemSessionCollection = (ItemSessionCollection)BinaryFormatter.deserialize(path);
        }
        else
        {
            oItemSessionCollection = new ItemSessionCollection();
            //stream = File.Open(path, FileMode.Create);
            f.createNewFile();
            BinaryFormatter.serialize(oItemSessionCollection,path);
        }
        //stream.Close();
    }

    public static void Remove(HttpSession session,HttpServletRequest request,HttpServletResponse response,String strKey) throws Exception
    {
        if (!IsOpen())
        {
            throw new SessionNotOpenException();
        }
        if (oItemSessionCollection.Contains(strKey))
        {
            oItemSessionCollection.remove(oItemSessionCollection.IndexOf(strKey));
        }
    }

    public static void Set(HttpSession session,HttpServletRequest request,HttpServletResponse response,String strKey, Object obj) throws Exception
    {
        if (!IsOpen())
        {
            throw new SessionNotOpenException();
        }
        ItemSession oItem = new ItemSession();
        oItem.setKey(strKey);
        oItem.setContent(obj);
        if (oItemSessionCollection.Contains(strKey))
        {
            oItemSessionCollection.remove(oItemSessionCollection.IndexOf(strKey));
        }
        oItemSessionCollection.Add(oItem);
    }
    
 
    public static String getSessionFolder(HttpSession session,HttpServletRequest request,HttpServletResponse response)
    {
       return m_strFolderName;
    }
    public static void setSessionFolder(HttpSession session,HttpServletRequest request,HttpServletResponse response,String value)
        {
            if (value != null)
            {
                value = value.trim();
                if ((value.length() > 0) && ((value.substring(value.length() - 1, (value.length() - 1) +  value.length()).equals("/")) || (value.substring(value.length() - 1,(value.length() - 1) + value.length()).equals("\\"))))
                {
                    value = value.substring(0, value.length() - 1);
                }
            }
            m_strFolderName = value;
        }
            
    
    
    
    
    
    
    
    
    
    
    
    public static void SetUsuario(HttpSession session,HttpServletRequest request,HttpServletResponse response,UsuarioSesion oUsuario) throws Exception
    {
        try
        {
            if (!IsOpen())
                Open(session,request,response);
            Set(session,request,response,Constantes.USUARIO_SESSION, oUsuario);
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (IsOpen()) Close(session,request,response);
        }
    }  
    
    public static UsuarioSesion GetUsuario(HttpSession session,HttpServletRequest request,HttpServletResponse response) throws Exception
    {
        try
        {
            if (!IsOpen())
                Open(session,request,response);
            if (Contains(session,request,response,Constantes.USUARIO_SESSION))
            {
                return (UsuarioSesion)Get(session,request,response,Constantes.USUARIO_SESSION);
            }
            else{
                return null;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        finally
        {
            if (IsOpen()) Close(session,request,response);
        }
    }
    
   
    public static void SetNombreUsuario(HttpSession session,HttpServletRequest request,HttpServletResponse response,String sNombre) throws Exception
    {
        try
        {
            if (!IsOpen())
                Open(session,request,response);
            Set(session,request,response,Constantes.NOMBRE_USUARIO_SESSION, sNombre);
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (IsOpen()) Close(session,request,response);
        }
    }  
    
    public static String GetNombreUsuario(HttpSession session,HttpServletRequest request,HttpServletResponse response) throws Exception
    {
        try
        {
            if (!IsOpen())
                Open(session,request,response);
            if (Contains(session,request,response,Constantes.NOMBRE_USUARIO_SESSION))
            {
                return (String)Get(session,request,response,Constantes.NOMBRE_USUARIO_SESSION);
            }
            else{
                return null;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        finally
        {
            if (IsOpen()) Close(session,request,response);
        }
    }
    
    
    public static void SetFecha(HttpSession session,HttpServletRequest request,HttpServletResponse response,String sFecha) throws Exception
    {
        try
        {
            if (!IsOpen())
                Open(session,request,response);
            Set(session,request,response,Constantes.FECHA_SESSION, sFecha);
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (IsOpen()) Close(session,request,response);
        }
    }  
    
    public static String GetFecha(HttpSession session,HttpServletRequest request,HttpServletResponse response) throws Exception
    {
        try
        {
            if (!IsOpen())
                Open(session,request,response);
            if (Contains(session,request,response,Constantes.FECHA_SESSION))
            {
                return (String)Get(session,request,response,Constantes.FECHA_SESSION);
            }
            else{
                return null;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        finally
        {
            if (IsOpen()) Close(session,request,response);
        }
    }
    
    
    public static void SetVectorMenu(HttpSession session,HttpServletRequest request,HttpServletResponse response,Vector oVector) throws Exception
    {
        try
        {
            if (!IsOpen())
                Open(session,request,response);
            Set(session,request,response,Constantes.FECHA_SESSION, oVector);
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (IsOpen()) Close(session,request,response);
        }
    }  
    
    public static Vector GetVectorMenu(HttpSession session,HttpServletRequest request,HttpServletResponse response) throws Exception
    {
        try
        {
            if (!IsOpen())
                Open(session,request,response);
            if (Contains(session,request,response,Constantes.FECHA_SESSION))
            {
                return (Vector)Get(session,request,response,Constantes.FECHA_SESSION);
            }
            else{
                return null;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        finally
        {
            if (IsOpen()) Close(session,request,response);
        }
    }

  
     
}
